﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.ComponentModel;

namespace XWord.WPF.ApplicationFramework.Validations
{
    public class CompareValidator : Validator
    {


        private TypeConverter converter;

        public override bool Validate()
        {
            if (this.ValueToCompare == null && this.Property == null) return true;
            if (IsFail()) return false;
            //if (this.ValueToCompare == null || this.Property == null || string.IsNullOrEmpty(this.Property.ToString()) || string.IsNullOrEmpty(this.ValueToCompare.ToString())) return true;
            if (Operator == ValidationCompareOperator.DataTypeCheck)
            {
                return this.Property.GetType().Equals(ValueToCompare.GetType());
            }
            if (converter == null) converter = new StringConverter();
            var convertProperty = converter.ConvertFrom(this.Property);
            var convertValueToCompare = converter.ConvertFrom(this.ValueToCompare);
            var propery = convertProperty as IComparable;
            int num = propery.CompareTo(convertValueToCompare);
            switch (Operator)
            {
                case ValidationCompareOperator.Equal:
                    return (num == 0);

                case ValidationCompareOperator.NotEqual:
                    return (num != 0);

                case ValidationCompareOperator.GreaterThan:
                    return (num > 0);

                case ValidationCompareOperator.GreaterThanEqual:
                    return (num >= 0);

                case ValidationCompareOperator.LessThan:
                    return (num < 0);

                case ValidationCompareOperator.LessThanEqual:
                    return (num <= 0);
            }
            return true;
        }

        private bool IsFail()
        {
            return (this.ValueToCompare == null && this.Property != null) || (this.ValueToCompare != null && this.Property == null) ||
            (String.IsNullOrEmpty(this.ValueToCompare.ToString().Trim()) && !String.IsNullOrEmpty(this.Property.ToString().Trim())) ||
            (!String.IsNullOrEmpty(this.ValueToCompare.ToString().Trim()) && String.IsNullOrEmpty(this.Property.ToString().Trim()));
        }

        public Type Type
        {
            get { return (Type)GetValue(TypeProperty); }
            set { SetValue(TypeProperty, value); }
        }

        public static readonly DependencyProperty TypeProperty =
            DependencyProperty.Register("Type", typeof(Type), typeof(CompareValidator),
            new UIPropertyMetadata(new PropertyChangedCallback((sender, args) =>
            {
                CompareValidator validator = sender as CompareValidator;
                if (args.NewValue != null)
                    validator.converter = TypeDescriptor.GetConverter(validator.Type);
            })));

        public object ValueToCompare
        {
            get { return (object)GetValue(ValueToCompareProperty); }
            set { SetValue(ValueToCompareProperty, value); }
        }

        public static readonly DependencyProperty ValueToCompareProperty =
            DependencyProperty.Register("ValueToCompare", typeof(object), typeof(CompareValidator)
            , new UIPropertyMetadata(null));

        public ValidationCompareOperator Operator { get; set; }
    }

    public enum ValidationCompareOperator
    {
        Equal,
        NotEqual,
        GreaterThan,
        GreaterThanEqual,
        LessThan,
        LessThanEqual,
        DataTypeCheck
    }
}
